﻿using ControlCore;
using ControlCore.Controller;
using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.Windows;

namespace KeyboardController
{
    [Export(typeof(IController))]
    [ExportMetadata("Name", "Keyboard controller")]
    public class KeyboardController : IController
    {
        public event EventHandler<ControllerCommandEventArgs> CommandReceived;

        private readonly VisualOutput visualOutput;

        private IDictionary<System.Windows.Input.Key, Tuple<ControlCommand, double>> keyBindings;

        public bool IsInitialized { get; private set; }

        FrameworkElement IController.ControllerOutput
        {
            get { return visualOutput; }
        }

        public KeyboardController()
        {
            this.visualOutput = new VisualOutput();
            this.keyBindings = defaultBindings();
        }

        public void Init()
        {
            visualOutput.ChangeText("Init");
            Application.Current.MainWindow.KeyUp += MainWindow_KeyUp;
            IsInitialized = true;
        }

        public void Close()
        {
            this.visualOutput.ChangeText("Shutdown");
            Application.Current.MainWindow.KeyUp -= MainWindow_KeyUp;
            IsInitialized = false;
        }

        private Dictionary<System.Windows.Input.Key, Tuple<ControlCommand, double>> defaultBindings()
        {
            var bindingCollection = new Dictionary<System.Windows.Input.Key, Tuple<ControlCommand, double>>();
            bindingCollection.Add(System.Windows.Input.Key.Enter, new Tuple<ControlCommand, double>(ControlCommand.Start, 0));
            bindingCollection.Add(System.Windows.Input.Key.Space, new Tuple<ControlCommand, double>(ControlCommand.Stop, 0));
            bindingCollection.Add(System.Windows.Input.Key.PageUp, new Tuple<ControlCommand, double>(ControlCommand.Accelerate, 1));
            bindingCollection.Add(System.Windows.Input.Key.PageDown, new Tuple<ControlCommand, double>(ControlCommand.Decelerate, 1));
            bindingCollection.Add(System.Windows.Input.Key.Up, new Tuple<ControlCommand, double>(ControlCommand.Forward, 1));
            bindingCollection.Add(System.Windows.Input.Key.Down, new Tuple<ControlCommand, double>(ControlCommand.Backward, 1));
            bindingCollection.Add(System.Windows.Input.Key.Left, new Tuple<ControlCommand, double>(ControlCommand.Turn, -1));
            bindingCollection.Add(System.Windows.Input.Key.Right, new Tuple<ControlCommand, double>(ControlCommand.Turn, 1));
            return bindingCollection;
        }

        private void MainWindow_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            if (keyBindings.ContainsKey(e.Key))
            {
                var commandInput = this.keyBindings[e.Key];
                this.visualOutput.AppendTextLine(System.Enum.GetName(typeof(System.Windows.Input.Key), e.Key)
                    + " : "
                    + commandInput.Item1
                    + " = "
                    + commandInput.Item2);
                CommandReceived(this, new ControllerCommandEventArgs(commandInput.Item1, commandInput.Item2));
            }
        }
    }
}
